/*
 * The MIT License
 * Copyright (c) 2012 kc4.org
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.kc4.sso.session;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yoichi kikuchi
 */
public class SSOSession implements Serializable {

	private static final String EMPTY = "";

	private static final long serialVersionUID = 1L;

	private String authorizationToken;
	private Map<String, String> activeClients = this.newActiveClients();
	private Serializable userObject;
	private String commonkey;

	/**
	 * {@link SSOSession} インスタンスを生成します。
	 *
	 * @param authorizationToken 認証トークン。
	 */
	public SSOSession(String authorizationToken) {

		if (authorizationToken == null) {

			throw new NullPointerException("authorizationToken is null.");
		}

		this.setAuthorizationToken(authorizationToken);
	}

	/**
	 * サインオン中のクライアント数を取得します。
	 *
	 * @return サインオン中のクライアント数。
	 */
	public int getActiveClientSize() {

		int size = 0;

		for (String v : this.getActiveClients().values()) {

			if (v != null && !v.isEmpty()) {

				++size;
			}
		}

		return size;
	}

	/**
	 * クライアントのサインオン状態が有効がどうかを取得します。
	 *
	 * @param contextUrl クライアントのコンテキスト URL。
	 * @return サインオン状態が有効な場合は ture、それ以外の場合は false。
	 */
	public boolean isActiveClient(String contextUrl) {

		String publickey = getActiveClientPublickey(contextUrl);

		return publickey == null || !publickey.isEmpty();
	}

	/**
	 * クライアントのサインオン状態管理のために保存している公開鍵を取得します。
	 *
	 * @param contextUrl クライアントのコンテキスト URL。
	 * @return 公開鍵。
	 */
	public String getActiveClientPublickey(String contextUrl) {

		return this.getActiveClients().get(contextUrl);
	}

	/**
	 * クライアントのサインオン状態を有効化します。
	 *
	 * @param contextUrl クライアントのコンテキスト URL。
	 * @param publickey 公開鍵。
	 */
	public void activateClient(String contextUrl, String publickey) {

		if (publickey != null) {

			this.getActiveClients().put(contextUrl, publickey);
		}
	}

	/**
	 * クライアントのサインオン状態を無効化します。
	 *
	 * @param contextUrl クライアントのコンテキスト URL。
	 */
	public void inactivateClient(String contextUrl) {

		this.getActiveClients().put(contextUrl, EMPTY);
	}

	/**
	 * authorizationToken を取得します。
	 *
	 * @return authorizationToken オブジェクト。
	 */
	public String getAuthorizationToken() {
		return this.authorizationToken;
	}

	/**
	 * authorizationToken を設定します。
	 *
	 * @param authorizationToken authorizationToken オブジェクト。
	 */
	public void setAuthorizationToken(String authorizationToken) {
		this.authorizationToken = authorizationToken;
	}

	/**
	 * activeClients を生成します。
	 *
	 * @return activeClients オブジェクト。
	 */
	protected Map<String, String> newActiveClients() {
		return new HashMap<String, String>();
	}

	/**
	 * activeClients を取得します。
	 *
	 * @return activeClients オブジェクト。
	 */
	protected Map<String, String> getActiveClients() {
		return this.activeClients;
	}

	/**
	 * activeClients を設定します。
	 *
	 * @param activeClients activeClients オブジェクト。
	 */
	protected void setActiveClients(Map<String, String> activeClients) {
		this.activeClients = activeClients;
	}

	/**
	 * userObject を取得します。
	 *
	 * @return userObject オブジェクト。
	 */
	public Serializable getUserObject() {
		return this.userObject;
	}

	/**
	 * userObject を設定します。
	 *
	 * @param userObject userObject オブジェクト。
	 */
	public void setUserObject(Serializable userObject) {
		this.userObject = userObject;
	}

	/**
	 * commonkey を取得します。
	 *
	 * @return commonkey オブジェクト。
	 */
	public String getCommonkey() {
		return this.commonkey;
	}

	/**
	 * commonkey を設定します。
	 *
	 * @param commonkey commonkey オブジェクト。
	 */
	public void setCommonkey(String commonkey) {
		this.commonkey = commonkey;
	}
}
